<template style="position: absolute;">
  <div id="containerPar">
    <div id="toolBar" style="position: absolute;top: 18px;right: 188px;z-index: 10">
      <span>是否采用自动布局：</span>
      <el-switch v-model="autoLayout"></el-switch>
    </div>
    <div id="container"></div>
  </div>
</template>

<script>
import G6 from "@antv/g6";
import renwu_url from "../../../static/images/task.png";
import renwuliu_url from "../../../static/images/renwuliu.png";
import start_url from "../../../static/images/start.png";
import end_url from "../../../static/images/end.png";
export default {
  data() {
    return {
      getOffsetWidth: Number,
      getOffsetHeight: Number,
      renwuSrc: renwu_url,
      renwuliuSrc: renwuliu_url,
      autoLayout: false,
      initData: {
        nodes: [
          {
            id: "2f59f55d6bbd4069a7bd661e581bc376",
            label: "LCAPPNT",
            x: 395,
            y: 45,
            taskFlowId: 64,
            sourceId: null,
            type: "inmission",
            size: null,
            styleJson: "null",
            color: "#FFD591",
            content: null,
            style: null,
            labelCfg: {
              style: {
                fontSize: 15,
                fill: "#000"
              }
            },
            status: null,
            taskFlowInstId: null,
            startTime: null,
            endTime: null,
            timeLag: null
          },
          {
            id: "803ae55818ae4d1eac9d63840f58c149",
            label: "LCCONT",
            x: 143,
            y: 308,
            taskFlowId: 64,
            sourceId: null,
            type: "inmission",
            size: null,
            styleJson: "null",
            color: "#FFD591",
            content: null,
            style: null,
            labelCfg: {
              style: {
                fontSize: 15,
                fill: "#000"
              }
            },
            status: null,
            taskFlowInstId: null,
            startTime: null,
            endTime: null,
            timeLag: null
          },
          {
            id: "f9c57c1406d0438da94dea0ffef45c36",
            label: "LCPOL",
            x: 685,
            y: 220,
            taskFlowId: 64,
            sourceId: null,
            type: "inmission",
            size: null,
            styleJson: "null",
            color: "#FFD591",
            content: null,
            style: null,
            labelCfg: {
              style: {
                fontSize: 15,
                fill: "#000"
              }
            },
            status: null,
            taskFlowInstId: null,
            startTime: null,
            endTime: null,
            timeLag: null
          },
          {
            id: "kir2rd728saiv",
            label: "结束",
            x: 975,
            y: 110,
            taskFlowId: 64,
            sourceId: null,
            type: "1",
            size: null,
            styleJson: "null",
            color: "#9FD4FB",
            content: null,
            style: null,
            labelCfg: {
              style: {
                fontSize: 15,
                fill: "#000"
              }
            },
            status: null,
            taskFlowInstId: null,
            startTime: null,
            endTime: null,
            timeLag: null
          },
          {
            id: "kir2rd72hhdy2",
            label: "开始",
            x: 518,
            y: 393,
            taskFlowId: 64,
            sourceId: null,
            type: "1",
            size: null,
            styleJson: "null",
            color: "#9FD4FB",
            content: null,
            style: null,
            labelCfg: {
              style: {
                fontSize: 15,
                fill: "#000"
              }
            },
            status: null,
            taskFlowInstId: null,
            startTime: null,
            endTime: null,
            timeLag: null
          }
        ],
        edges: [
          {
            id: 1270,
            taskFlowId: 64,
            target: "2f59f55d6bbd4069a7bd661e581bc376",
            source: "kir2rd72hhdy2",
            x: 403.83620689655174,
            y: 70,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1271,
            taskFlowId: 64,
            target: "803ae55818ae4d1eac9d63840f58c149",
            source: "kir2rd72hhdy2",
            x: 168,
            y: 313.6666666666667,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1272,
            taskFlowId: 64,
            target: "f9c57c1406d0438da94dea0ffef45c36",
            source: "kir2rd72hhdy2",
            x: 660.8670520231213,
            y: 245,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1273,
            taskFlowId: 64,
            target: "kir2rd728saiv",
            source: "2f59f55d6bbd4069a7bd661e581bc376",
            x: 950,
            y: 107.19827586206897,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1274,
            taskFlowId: 64,
            target: "kir2rd728saiv",
            source: "803ae55818ae4d1eac9d63840f58c149",
            x: 950,
            y: 115.94951923076923,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1275,
            taskFlowId: 64,
            target: "kir2rd728saiv",
            source: "f9c57c1406d0438da94dea0ffef45c36",
            x: 950,
            y: 119.48275862068965,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          },
          {
            id: 1276,
            taskFlowId: 64,
            target: "803ae55818ae4d1eac9d63840f58c149",
            source: "2f59f55d6bbd4069a7bd661e581bc376",
            x: 166.95437262357416,
            y: 283,
            style: {
              endArrow: true,
              stroke: "#ccc",
              lineWidth: 2
            },
            dependType: null
          }
        ]
      }
    };
  },
  created() {},
  mounted() {
    this.getOffsetWidth = document.getElementById("containerPar").offsetWidth;
    this.getOffsetHeight = document.getElementById("containerPar").offsetHeight;
    this.init();
  },
  methods: {
    init() {
      let _this = this;
      const toolbar = new G6.ToolBar({
        position: { x: this.getOffsetWidth - 165, y: 10 }
      });

      // 实例化 minimap 插件
      const minimap = new G6.Minimap({
        size: [100, 100],
        className: "minimap",
        type: "delegate"
      });

      /**
       * 自定义节点
       */
      G6.registerNode(
        "node",
        {
          drawShape: function drawShape(cfg, group) {
            var rect = group.addShape("rect", {
              attrs: _extends(
                {
                  x: -75,
                  y: -25,
                  width: 150,
                  height: 50,
                  radius: 4,
                  fill: "#FFD591",
                  fillOpacity: 1
                },
                nodeExtraAttrs[cfg.type]
              )
            });
            return rect;
          },
          // 设置状态
          setState: function setState(name, value, item) {
            var group = item.getContainer();
            var shape = group.get("children")[0]; // 顺序根据 draw 时确定

            if (name === "selected") {
              if (value) {
                shape.attr("fill", "#F6C277");
              } else {
                shape.attr("fill", "#FFD591");
              }
            }
          },

          getAnchorPoints: function getAnchorPoints() {
            return [
              [0, 0.5],
              [1, 0.5]
            ];
          }
        },
        "single-shape"
      );

      /**
       * 自定义 edge 中心关系节点
       */
      G6.registerNode(
        "statusNode",
        {
          drawShape: function drawShape(cfg, group) {
            var circle = group.addShape("circle", {
              attrs: {
                x: 0,
                y: 0,
                r: 6,
                fill: cfg.active ? "#AB83E4" : "#ccc"
              }
            });
            return circle;
          }
        },
        "single-shape"
      );

      /**
       * 自定义带箭头的贝塞尔曲线 edge
       */
      G6.registerEdge("line-with-arrow", {
        itemType: "edge",
        draw: function draw(cfg, group) {
          var startPoint = cfg.startPoint;
          var endPoint = cfg.endPoint;
          var centerPoint = {
            x: (startPoint.x + endPoint.x) / 2,
            y: (startPoint.y + endPoint.y) / 2
          };
          // 控制点坐标
          var controlPoint = {
            x: (startPoint.x + centerPoint.x) / 2,
            y: startPoint.y
          };

          // 为了更好的展示效果, 对称贝塞尔曲线需要连到箭头根部
          var path = group.addShape("path", {
            attrs: {
              path: [
                ["M", startPoint.x, startPoint.y],
                [
                  "Q",
                  controlPoint.x + 8,
                  controlPoint.y,
                  centerPoint.x,
                  centerPoint.y
                ],
                ["T", endPoint.x - 8, endPoint.y],
                ["L", endPoint.x, endPoint.y]
              ],
              stroke: "#ccc",
              lineWidth: 1.6,
              endArrow: {
                // path: G6.Arrow.triangle(5, 10, 10),
                // d: 8
                path: "M 0,0 L 8,4 L 8,-4 Z",
                fill: "#e2e2e2"
              }
            }
          });

          // 如果是不对称的贝塞尔曲线，需要计算贝塞尔曲线上的中心点
          // 参考资料 https://stackoverflow.com/questions/54216448/how-to-find-a-middle-point-of-a-beizer-curve
          // 具体Util方法可以参考G：https://github.com/antvis/g/blob/4.x/packages/g-math/src/quadratic.ts

          // 在贝塞尔曲线中心点上添加圆形
          var source = cfg.source,
            target = cfg.target;

          group.addShape("circle", {
            attrs: {
              id: "statusNode" + source + "-" + target,
              r: 6,
              x: centerPoint.x,
              y: centerPoint.y,
              fill: cfg.active ? "#AB83E4" : "#ccc"
            }
          });

          return path;
        }
      });

      this.graph = new G6.Graph({
        container: "container",
        // width: 1160,
        // height: 460,
        width: this.getOffsetWidth,
        height: this.getOffsetHeight - 10,
        plugins: [toolbar, minimap], // 配置 ToolBar 插件
        modes: {
          default: ["drag-canvas", "zoom-canvas", "drag-node"] //默认模式：拖拽画布，缩放画布，拖拽节点
        },
        layout: {
          type: "dagre",
          rankdir: "LR",
          nodesep: 20, //节点之间的距离
          ranksep: 80 //线的长度
        },
        layout: this.myLayout,
        defaultNode: {
          type: "rect", //长方形
          color: "#9FD4FB", //边框颜色
          labelCfg: {
            style: {
              fill: "#000", //文字颜色
              fontSize: 15
            }
          }
        },
        defaultEdge: {
          type: "line-with-arrow",
          style: {
            endArrow: true,
            lineWidth: 2,
            stroke: "#ccc"
            // lineDash: [0, 2] //箭头样式
          }
        }
      });

      this.graph.data(this.initData);
      this.graph.render();
      if (this.showTittle == "新增任务流" || this.showTittle == "修改任务流") {
        // this.disabled = true
        // 1、节点左击 连线
        this.graph.on("node:click", evt => {
          let model = evt.item._cfg.model;
          // 结束节点不能往处连线  做限制----
          if (_this.sortArr.length == 0 && model.label == "结束") {
            _this.sortArr.length == 0;
          } else {
            let id = evt.item._cfg.model.id;
            _this.sortArr.push(id);
          }
          console.log(_this.sortArr);
          model.size = 60;
          this.graph.render();
          setTimeout(() => {
            model.size = 50;
          }, 1000);
          this.graph.render();
          // 定义的数组最大长度不能大于2
          if (_this.sortArr.length <= 2) {
            if (_this.sortArr.length == 2) {
              // console.log('_this.sortArr', _this.sortArr)
              // 定义一个标识，比较四种情况
              let flag = false;
              let edges = _this.initData.edges;
              let nodes = _this.initData.nodes;
              // 如果自己和自己连线 ，不可以
              if (_this.sortArr[0] == _this.sortArr[1]) {
                flag = false;
                return;
              }
              for (let i = 0; i < edges.length; i++) {
                let element = edges[i];
                if (
                  element.source == _this.sortArr[0] &&
                  element.target == _this.sortArr[1]
                ) {
                  flag = false;
                  return;
                } else {
                  flag = true;
                }
                if (
                  element.source == _this.sortArr[1] &&
                  element.target == _this.sortArr[0]
                ) {
                  flag = false;
                  return;
                } else {
                  flag = true;
                }
              }
              // 如果没有线的情况的可以连线
              if (edges.length == 0) {
                flag = true;
              }
              // 不能向开始节点连线
              let startModel = evt.item._cfg.model;
              if (
                _this.sortArr[1] == startModel.id &&
                startModel.label == "开始"
              ) {
                flag = false;
              }

              // 开始不能向结束链接
              let startId;
              let endId;
              for (let j = 0; j < nodes.length; j++) {
                const element = nodes[j];
                if (element.label == "开始") {
                  startId = element.id;
                }
                if (element.label == "结束") {
                  endId = element.id;
                }
              }
              if (startId == _this.sortArr[0] && endId == _this.sortArr[1]) {
                flag = false;
                return;
              } else {
                flag = true;
              }

              console.log("flag2----------", flag);
              if (flag == true) {
                _this.initData.edges.push({
                  source: _this.sortArr[0],
                  target: _this.sortArr[1]
                });
                _this.graph.data(this.initData);
                _this.graph.render();
              }
              _this.sortArr = [];
            }
          } else {
            _this.sortArr = [];
          }
          // style: {
          //     fill: 'green', //填充颜色
          //     lineWidth: 1
          //   },
          //   //节点标签的样式
          //   labelCfg: {
          //     style: {
          //       fill: 'red',
          //       fontSize: 14
          //     }
          //   }
        });
        //  2、节点右击   添加
        this.graph.on("node:contextmenu", evt => {
          let labelName = evt.item._cfg.model.label;
          if (labelName == "结束") {
            this.$message({
              type: "warning",
              duration: "2000",
              message: "结束节点不允许再新建"
            });
            return;
          }
          _this.treeDialog = true;
          if (_this.num == 2) {
            _this.num = 2;
            _this.$refs.myTree.setCheckedKeys([]);
          }
          _this.rightModel = evt.item._cfg.model.id;
        });
        // 4、线上 鼠标 双击事件 删除线
        this.graph.on("edge:dblclick", evt => {
          _this.inquiryDialog = false;
          var target = evt.target;
          let cfgId = evt.item._cfg.id;
          var type = target.get("type");
          if (type === "circle") {
            // 点击边上的circle
            // alert('删除线')
            _this
              .$confirm("确定要删除线吗?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
              })
              .then(() => {
                let edges = this.initData.edges;
                for (let i = 0; i < edges.length; i++) {
                  const element = edges[i];
                  if (cfgId == element.id) {
                    edges.splice(i, 1);
                    this.graph.data(this.initData);
                    this.graph.render();
                  }
                }
                this.$message({
                  message: "连接线已删除",
                  type: "success",
                  duration: "1000"
                });
              });
          }
        });
      }
      // 3、鼠标左键双击事件  询问 删除 或者打开弹框
      this.graph.on("dblclick", evt => {
        console.log(evt);
        _this.deleteInfo = evt.item._cfg;
        let labelName = evt.item._cfg.model.label;
        if (labelName == "开始") {
          this.$message({
            type: "warning",
            duration: "2000",
            message: "开始节点不允许删除"
          });
          return;
        }
        if (labelName == "结束") {
          this.$message({
            type: "warning",
            duration: "2000",
            message: "结束节点不允许删除"
          });
          return;
        }
        _this.inquiryDialog = true;
        if (
          labelName == "监控" ||
          labelName == "SQL脚本" ||
          labelName == "shell命令"
        ) {
          this.isdeleteInfo = true; //是否可以点击查看命令
          console.log(true);
        } else {
          console.log(false);
          this.isdeleteInfo = false;
        }
      });
      // 5、鼠标开始拖拽事件
      this.graph.on("dragstart", ev => {
        //删除 查看  打开命令行 不显示
        this.inquiryDialog = false;
        this.isdeleteInfo = false;
        // 清空连线数组
        // this.sortArr = []
      });
    }
  },
  watch: {
    autoLayout: function(val) {
      if (val == true) {
        this.myLayout = {
          type: "dagre",
          rankdir: "LR",
          nodesep: 20, //节点之间的距离
          ranksep: 80 //线的长度
        };
        this.graph.destroy();
        this.init();
      } else {
        this.myLayout = {
          type: ""
        };
        this.graph.destroy();
        this.init();
      }
    }
  }
};
</script>

<style lang="less" rel="stylesheet/less"   scoped>
#containerPar {
  width: 99%;
  height: 600px;
  border: 1px solid red;
}
/deep/.g6-component-toolbar li:nth-child(1),
/deep/.g6-component-toolbar li:nth-child(2) {
  display: none !important;
}
/deep/.minimap {
  position: absolute;
  right: 26px;
  top: 50px;
  border: 1px solid #f0f0f0;
  background-color: #fff;
}
.explain {
  height: 30px;
  line-height: 30px;
  // border:1px solid red;
  margin-top: -10px;
}
</style>
